package com.breaktian.assemble.threadpool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by keke.tian on 2018/2/28.
 *
 * 重点讲解：
 其中比较容易让人误解的是：corePoolSize，maximumPoolSize，workQueue之间关系。

 1.当线程池小于corePoolSize时，新提交任务将创建一个新线程执行任务，即使此时线程池中存在空闲线程。
 2.当线程池达到corePoolSize时，新提交任务将被放入workQueue中，等待线程池中任务调度执行
 3.当workQueue已满，且maximumPoolSize>corePoolSize时，新提交任务会创建新线程执行任务
 4.当提交任务数超过maximumPoolSize时，新提交任务由RejectedExecutionHandler处理
 5.当线程池中超过corePoolSize线程，空闲时间达到keepAliveTime时，关闭空闲线程
 6.当设置allowCoreThreadTimeOut(true)时，线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

 */

public class ThreadPool {


    private int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
    private int KEEP_ALIVE_TIME = 5;
    private TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.MINUTES;
    private BlockingQueue<Runnable> taskQueue;
    private ExecutorService executorService;

    public ThreadPool(){
        init();
    }

    static class InstanceHolder{
        public static ThreadPool instance = new ThreadPool();
    }

    public static ThreadPool get(){
        return InstanceHolder.instance;
    }



    /**
     corePoolSize 核心线程池大小
     maximumPoolSize 线程池最大容量大小
     keepAliveTime 线程池空闲时，线程存活的时间
     TimeUnit 时间单位
     ThreadFactory 线程工厂
     BlockingQueue任务队列
     RejectedExecutionHandler 线程拒绝策略
     * */
    private void init() {
        taskQueue = new LinkedBlockingQueue<Runnable>();
        executorService = new ThreadPoolExecutor(
                NUMBER_OF_CORES,
                NUMBER_OF_CORES*2,
                KEEP_ALIVE_TIME,
                KEEP_ALIVE_TIME_UNIT,
                taskQueue,
                new BackgroundThreadFactory(),new DefaultRejectedExecutionHandler());
    }

    /**
     * 执行任务
     * */
    public void execute(Runnable runnable){
        executorService.execute(runnable);
    }


}
